/*
 * The forum Data Access Object, it handles all database transactions between the front end and the database.
 */

package airport.forum.dao;

//import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.LinkedList;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;

import airport.forum.pojo.Forum;
import airport.forum.pojo.Thread;
//forumdao
@SuppressWarnings("deprecation")
public class ForumDAO {
	//test push
	private static SessionFactory factory = new AnnotationConfiguration().configure().addAnnotatedClass(Forum.class).addPackage("com.xyz").buildSessionFactory();
	
	//adds the given thread to the forum whose ID is specified
	public void addThreadToForum(Thread thread, Long forumId) {
		try {
			Session session = factory.openSession();
			Transaction tx = null;
			try {
				System.out.println("***<ForumDAO>:addThreadToForum***");
				tx = session.beginTransaction();
				Forum forum = (Forum) session.load(Forum.class, forumId);
				System.out.println("Going to add threads");
				forum.addThread(thread);
				System.out.println("After adding");
				session.update(forum);
				tx.commit();
				System.out.println("---<ForumDAO>:addThreadToForum---");
			} 
			catch (HibernateException e) {
				if (tx!=null) 
	        		 tx.rollback();
				e.printStackTrace();
			}
			finally {
				session.close();
			}
		}
		catch (Throwable ex) { 
			System.err.println("Failed to create sessionFactory object." + ex);
			throw new ExceptionInInitializerError(ex);
        }
	}
	
	//gets a set containing all the threads in a forum
	public Set<Thread> getAllThreadsFromForum(Long forumId) {
		Set<Thread> threads = null;
		try {
			Session session = factory.openSession();
			try {
				System.out.println("***<ForumDAO>:getAllThreadsFromForum***");
				Forum forum = (Forum) session.load(Forum.class, forumId);
				threads = forum.getThreadList();
				System.out.println("thread number: "+threads.size());
				/**
				 * iteratively work through the set
				 */
				//if (threads != null) {
				//	Iterator<Thread> it = threads.iterator();
				//	while (it.hasNext()) {
				//		Thread thread = it.next();
				//		System.out.println(thread.getThreadId());
				//	}					
				//}
				System.out.println("---<ForumDAO>:getAllThreadsFromForum---");
			}
			catch (HibernateException e) {
				e.printStackTrace();
			}
			finally {
				session.close();
			}
		}
		catch (Throwable ex) { 
	         System.err.println("Failed to create sessionFactory object." + ex);
	         throw new ExceptionInInitializerError(ex);
	    }
		return threads;
	}
	
	//gets a list of all the threads per page, where the thread count is specified in the parameters
	public LinkedList<Thread> getThreadsByPage (Long forumId, int page, int pageSize) {
		LinkedList <Thread> threads = null;
		try {
			Session session =  factory.openSession();
			try {
				System.out.println("***<ForumDAO>:getThreadsByPage***");
				Forum forum = (Forum) session.load(Forum.class, forumId);
				Set <Thread> allThreads = forum.getThreadList();
				int size = allThreads.size();
				System.out.println("thread number: "+size);
				int lastPageLen = size%pageSize;
				int numPage = 0;
				if (lastPageLen == 0) {
					numPage = size/pageSize;
				}
				else {
					numPage = size/pageSize +1;
				}
				System.out.println("The threads can be display in "+numPage + " pages.");
				if (page > numPage ) {
					System.out.println("!!!Invalid Parameter: page. ");
				}
				else {
					int start = (page - 1) * pageSize;
					System.out.println("start page: "+ start);
					Iterator<Thread> it = allThreads.iterator();
					for (int i = 0; i < start; i ++) {
						System.out.println("Go to the right page to start");
						if (it.hasNext()) {
							it.next();
						}
					}
					threads =  new LinkedList<Thread>();
					System.out.println("Going to add threads to linkedlist.");
					if (page != numPage) {
						for (int j = 0; j < pageSize; j++) {
							if (it.hasNext()) {
								Thread thread = it.next();
								System.out.println("current thread id: "+ thread.getThreadId());
								threads.add(thread);
							}
						}
					}
					else {
						if (lastPageLen == 0)
							lastPageLen = pageSize;
						for (int j = 0; j < lastPageLen; j++) {
							if (it.hasNext()) {
								Thread thread = it.next();
								System.out.println("current thread id: "+ thread.getThreadId());
								threads.add(thread);
							}
						}
					}
				}
				
				System.out.println("---<ForumDAO>:getThreadsByPage---");
			}
			catch (HibernateException e) {
				e.printStackTrace();
			}
			finally {
				session.close();
			}
		}
		catch (Throwable ex) {
			System.err.println("Failed to create sessionFactory object." + ex);
			throw new ExceptionInInitializerError(ex);
		}
		return threads;
	}
	
	//retrieves a forum using the forum id
	@SuppressWarnings("unchecked")
	public Forum getForum (long id) {
		Forum forum = null;
		try {
	         Session session = factory.openSession();
	         try {
	        	 System.out.println("start query");
	        	 String hql = "FROM Forum F where F.forumId = '"+id+"'";
	        	 System.out.println(hql);
	        	 Query query = session.createQuery(hql);
	        	 List<Forum> results = query.list();
	        	 System.out.println("forum number:"+results.size());
	        	 if (results.size() != 0) {
	        		 forum = results.get(0);
	        		 System.out.println("forum found!"); 
	        	 	}
	        	 else
	        	 	System.out.println("no forum found");
	        	 
	        	 } 
	         catch (HibernateException e) {
	        	 e.printStackTrace();
	         } 
	         finally {
	            session.close(); 
	         }
	      } catch (Throwable ex) { 
	         System.err.println("Failed to create sessionFactory object." + ex);
	         throw new ExceptionInInitializerError(ex);
	      }
		return forum;
	}
	
	

}
